package com.thomsonreuter.search.compare.comparision;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONString;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;
import org.skyscreamer.jsonassert.JSONParser;
import org.skyscreamer.jsonassert.comparator.JSONComparator;

public final class JsonComparer {

    private JsonComparer() {
    }

    private static JSONComparator getComparatorForMode(JSONCompareMode mode) {
        return new CatComparator(mode);
    }

    public static JSONCompareResult compareJSON(String expectedStr, String actualStr, JSONComparator comparator) throws JSONException {
        Object expected = JSONParser.parseJSON(expectedStr);
        Object actual = JSONParser.parseJSON(actualStr);
        if (expected instanceof JSONObject && actual instanceof JSONObject) {
            return compareJSON((JSONObject)expected, (JSONObject)actual, comparator);
        } else if (expected instanceof JSONArray && actual instanceof JSONArray) {
            return compareJSON((JSONArray)expected, (JSONArray)actual, comparator);
        } else if (expected instanceof JSONString && actual instanceof JSONString) {
            return compareJson((JSONString)expected, (JSONString)actual);
        } else {
            return expected instanceof JSONObject ? (new JSONCompareResult()).fail("", expected, actual) : (new JSONCompareResult()).fail("", expected, actual);
        }
    }

    public static JSONCompareResult compareJSON(JSONObject expected, JSONObject actual, JSONComparator comparator) throws JSONException {
        return comparator.compareJSON(expected, actual);
    }

    public static JSONCompareResult compareJSON(JSONArray expected, JSONArray actual, JSONComparator comparator) throws JSONException {
        return comparator.compareJSON(expected, actual);
    }

    public static JSONCompareResult compareJson(JSONString expected, JSONString actual) {
        JSONCompareResult result = new JSONCompareResult();
        String expectedJson = expected.toJSONString();
        System.out.println(expectedJson);
        String actualJson = actual.toJSONString();
        System.out.println(actualJson);
        if (!filterSpecialCharacters(expectedJson).equals(filterSpecialCharacters(actualJson))) {

            result.fail("");
        }

        return result;
    }

    public static JSONCompareResult compareJSON(String expectedStr, String actualStr, JSONCompareMode mode) throws JSONException {
        return compareJSON(expectedStr, actualStr, getComparatorForMode(mode));
    }

    public static JSONCompareResult compareJSON(JSONObject expected, JSONObject actual, JSONCompareMode mode) throws JSONException {
        return compareJSON(expected, actual, getComparatorForMode(mode));
    }

    public static JSONCompareResult compareJSON(JSONArray expected, JSONArray actual, JSONCompareMode mode) throws JSONException {
        return compareJSON(expected, actual, getComparatorForMode(mode));
    }

    private static String filterSpecialCharacters(String content){
        return content.replaceAll(" ","").replaceAll("\r\n", "").replaceAll("\n","");
    }
}
